package scatter.recommend.rest.recommend.impl;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import scatter.recommend.rest.recommend.IRecommendFramework;
import scatter.recommend.rest.recommend.IRecommenderChain;
import scatter.recommend.rest.recommend.dto.RecommendResultDto;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 抽象推荐框架模板类
 * </p>
 *
 * @author yangwei
 * @since 2021-08-28 13:15
 */
@Slf4j
public abstract class AbstractRecommendFramework implements IRecommendFramework {


	@Override
	public List<RecommendResultDto> recommend(String userId, int recommendNum,String category) {
		if (StrUtil.isEmpty(userId)) {
			log.warn("推荐的用户id为空，部分推荐算法将不生效");
		}

		return doRecommend(userId, recommendNum,category);
	}

	/**
	 * 实际执行推荐
	 * @param userId
	 * @param recommendNum
	 * @return
	 */
	protected List<RecommendResultDto> doRecommend(String userId, int recommendNum,String category){

		List<RecommendResultDto> recommendResultDtos = new ArrayList<>(recommendNum);
		// 进行推荐逻辑处理
		newRecommenderChain(category).doRecommend(userId,recommendNum,recommendResultDtos);

		// 按权重由高到低排序
		return recommendResultDtos.stream()
				.sorted(Comparator.comparing(RecommendResultDto::getWeight).reversed())
				.collect(Collectors.toList());
	}

	/**
	 * 生成新的推荐器链
	 * @return
	 */
	protected abstract IRecommenderChain newRecommenderChain(String category);
}
